﻿using YDT_SeckillService.Domain.Enums;

namespace YDT_SeckillService.Domain.Entities
{
    /// <summary>
    /// 秒杀商品实体 - 属于秒杀活动聚合的一部分
    /// </summary>
    public class SeckillProduct : Entity
    {
        /// <summary>秒杀类型</summary>
        public SeckillType SeckillType { get; private set; }
        /// <summary>秒杀名称</summary>
        public string SeckillName { get; private set; }
        /// <summary>秒杀URL</summary>
        public string SeckillUrl { get; private set; }
        /// <summary>秒杀价格</summary>
        public decimal SeckillPrice { get; private set; }
        /// <summary>秒杀库存</summary>
        public int SeckillStock { get; private set; }
        /// <summary>秒杀百分比（进度显示）</summary>
        public string SeckillPercent { get; private set; }
        /// <summary>秒杀时间编号（外键）</summary>
        public Guid TimeId { get; private set; }
        /// <summary>商品编号</summary>
        public Guid ProductId { get; private set; }
        /// <summary>秒杀限制数量（每人限购）</summary>
        public int SeckillLimit { get; private set; }
        /// <summary>秒杀描述</summary>
        public string SeckillDescription { get; private set; }
        /// <summary>秒杀是否置顶</summary>
        public bool SeckillIsTop { get; private set; }
        /// <summary>秒杀状态</summary>
        public SeckillProductStatus SeckillStatus { get; private set; }
        /// <summary>原始库存（用于计算百分比）</summary>
        public int OriginalStock { get; private set; }
        /// <summary>创建时间</summary>
        public DateTime CreateTime { get; private set; }
        /// <summary>更新时间</summary>
        public DateTime UpdateTime { get; set; }

        /// <summary>
        /// 受保护的构造函数 - 用于EF Core
        /// </summary>
        protected SeckillProduct() { }

        /// <summary>
        /// 创建秒杀商品构造函数
        /// </summary>
        public SeckillProduct(Guid timeId, Guid productId, string seckillName, string seckillUrl,
                             decimal seckillPrice, int seckillStock, int seckillLimit,
                             string seckillDescription, SeckillType seckillType = SeckillType.Normal)
        {
            Id = Guid.NewGuid();
            TimeId = timeId;
            ProductId = productId;
            SeckillName = seckillName;
            SeckillUrl = seckillUrl;
            SeckillPrice = seckillPrice;
            SeckillStock = seckillStock;
            OriginalStock = seckillStock; // 保存原始库存用于计算百分比
            SeckillLimit = seckillLimit;
            SeckillDescription = seckillDescription;
            SeckillType = seckillType;
            SeckillIsTop = false;
            SeckillStatus = SeckillProductStatus.Active; // 默认激活状态
            CreateTime = DateTime.UtcNow;
            UpdateTime = DateTime.UtcNow;

            // 计算初始百分比
            UpdateSeckillPercent();

            // 验证业务规则
            ValidateCreation();
        }

        /// <summary>
        /// 更新秒杀商品信息
        /// </summary>
        public void UpdateInfo(string seckillName, string seckillUrl, decimal seckillPrice,
                              int seckillStock, int seckillLimit, string seckillDescription)
        {
            SeckillName = seckillName;
            SeckillUrl = seckillUrl;
            SeckillPrice = seckillPrice;
            SeckillStock = seckillStock;
            SeckillLimit = seckillLimit;
            SeckillDescription = seckillDescription;
            UpdateTime = DateTime.UtcNow;

            ValidateInfo();
        }

        /// <summary>
        /// 减少秒杀库存
        /// </summary>
        public void DecreaseStock(int quantity)
        {
            if (quantity <= 0)
                throw new ArgumentException("减少数量必须大于0");

            if (SeckillStock < quantity)
                throw new InvalidOperationException("秒杀库存不足");

            SeckillStock -= quantity;
            UpdateSeckillPercent();
            UpdateTime = DateTime.UtcNow;
        }

        /// <summary>
        /// 增加秒杀库存
        /// </summary>
        public void IncreaseStock(int quantity)
        {
            if (quantity <= 0)
                throw new ArgumentException("增加数量必须大于0");

            SeckillStock += quantity;
            OriginalStock += quantity; // 同时增加原始库存
            UpdateSeckillPercent();
            UpdateTime = DateTime.UtcNow;
        }

        /// <summary>
        /// 设置置顶状态
        /// </summary>
        public void SetTop(bool isTop)
        {
            SeckillIsTop = isTop;
            UpdateTime = DateTime.UtcNow;
        }

        /// <summary>
        /// 激活秒杀商品
        /// </summary>
        public void Activate()
        {
            SeckillStatus = SeckillProductStatus.Active;
            UpdateTime = DateTime.UtcNow;
        }

        /// <summary>
        /// 禁用秒杀商品
        /// </summary>
        public void Deactivate()
        {
            SeckillStatus = SeckillProductStatus.Inactive;
            UpdateTime = DateTime.UtcNow;
        }

        /// <summary>
        /// 结束秒杀商品
        /// </summary>
        public void End()
        {
            SeckillStatus = SeckillProductStatus.Ended;
            UpdateTime = DateTime.UtcNow;
        }

        /// <summary>
        /// 检查是否可购买
        /// </summary>
        public bool CanPurchase()
        {
            return SeckillStatus == SeckillProductStatus.Active && SeckillStock > 0;
        }

        /// <summary>
        /// 更新秒杀百分比
        /// </summary>
        private void UpdateSeckillPercent()
        {
            if (OriginalStock <= 0)
            {
                SeckillPercent = "0%";
                return;
            }

            var sold = OriginalStock - SeckillStock;
            var percent = (double)sold / OriginalStock * 100;
            SeckillPercent = $"{percent:F1}%";
        }

        /// <summary>
        /// 验证秒杀商品创建时的业务规则
        /// </summary>
        private void ValidateCreation()
        {
            if (string.IsNullOrWhiteSpace(SeckillName))
                throw new ArgumentException("秒杀名称不能为空");

            if (SeckillPrice <= 0)
                throw new ArgumentException("秒杀价格必须大于0");

            if (SeckillStock <= 0)
                throw new ArgumentException("秒杀库存必须大于0");

            if (SeckillLimit <= 0)
                throw new ArgumentException("秒杀限制数量必须大于0");
        }

        /// <summary>
        /// 验证基本信息
        /// </summary>
        private void ValidateInfo()
        {
            if (string.IsNullOrWhiteSpace(SeckillName))
                throw new ArgumentException("秒杀名称不能为空");

            if (SeckillPrice <= 0)
                throw new ArgumentException("秒杀价格必须大于0");

            if (SeckillStock < 0)
                throw new ArgumentException("秒杀库存不能为负数");

            if (SeckillLimit <= 0)
                throw new ArgumentException("秒杀限制数量必须大于0");
        }
    }
}
